package Tests
{
	import Box2D.Collision.Shapes.b2CircleShape;
	import Box2D.Collision.Shapes.b2EdgeShape;
	import Box2D.Collision.Shapes.b2PolygonShape;
	import Box2D.Common.Math.b2Vec2;
	import Box2D.Common.Math.b2Vec2Array;
	import Box2D.Common.b2Base;
	import Box2D.Dynamics.Joints.b2RevoluteJoint;
	import Box2D.Dynamics.Joints.b2RevoluteJointDef;
	import Box2D.Dynamics.b2Body;
	import Box2D.Dynamics.b2BodyDef;
	import Box2D.Dynamics.b2BodyType;
	import Box2D.Dynamics.b2FixtureDef;
	
	import Framework.Test;
	
	public class Revolute extends Test
	{
		private var m_ball:b2Body;
		private var m_joint:b2RevoluteJoint
		private var ground:b2Body;
		public function Revolute()
		{
			super();
			createGround();
			createJoint();
			createBall();
			createSmall();
		}
		private function createGround():void{
			var bd:b2BodyDef = new b2BodyDef;
			ground = m_world.CreateBody(bd);
			
			var shape:b2EdgeShape = new b2EdgeShape;
			shape.Set(new b2Vec2(-40,0),new b2Vec2(40,0));
			
			var fd:b2FixtureDef = new b2FixtureDef;
			fd.shape = shape;
			
			ground.CreateFixture(fd);
		}
		private function createJoint():void{
			var shape:b2CircleShape = new b2CircleShape;
			shape.radius = .5;
			var bd:b2BodyDef = new b2BodyDef;
			bd.type = b2BodyType.b2_dynamicBody;
			
			var rjd:b2RevoluteJointDef = new b2RevoluteJointDef;
			
			bd.position.Set(-10,20);
			var body:b2Body = m_world.CreateBody(bd);
			body.CreateFixtureByShape(shape,5);
			
			var w:Number = 100;
			body.SetAngularVelocity(w);
			body.SetLinearVelocity(new b2Vec2(-8*w,0));
			
			rjd.Initialize(ground,body,new b2Vec2(-10,12));
			rjd.motorSpeed = 1*Math.PI;
			rjd.maxMotorTorque = 10000;
			rjd.enableMotor = false;
			rjd.lowerAngle = -.25*Math.PI;
			rjd.upperAngle = .5*Math.PI;
			rjd.enableLimit = true;
			rjd.collideConnected = true;
			
			m_joint = m_world.CreateJoint(rjd) as b2RevoluteJoint;
		}
		private function createBall():void{
			var circle_shape:b2CircleShape = new b2CircleShape;
			circle_shape.radius = 3.0;
			
			var circle_bd:b2BodyDef = new b2BodyDef;
			circle_bd.type = b2BodyType.b2_dynamicBody;
			circle_bd.position.Set(5.0, 30.0);
			
			var fd:b2FixtureDef = new b2FixtureDef;
			fd.density = 5.0;
			fd.filter.maskBits = 1;
			fd.shape = circle_shape;
			
			m_ball = m_world.CreateBody(circle_bd);
			m_ball.CreateFixture(fd);
			
			var polygon_shape:b2PolygonShape = new b2PolygonShape;
			polygon_shape.SetAsBoxByCenter(10.0, 0.2, new b2Vec2 (-10.0, 0.0), 0.0);
			
			var polygon_bd:b2BodyDef = new b2BodyDef
			polygon_bd.position.Set(20.0, 10.0);
			polygon_bd.type = b2BodyType.b2_dynamicBody;
			polygon_bd.bullet = true;
			var polygon_body:b2Body = m_world.CreateBody(polygon_bd);
			polygon_body.CreateFixtureByShape(polygon_shape, 2.0);
			
			var rjd:b2RevoluteJointDef = new b2RevoluteJointDef
			rjd.Initialize(ground, polygon_body, new b2Vec2(20.0, 10.0));
			rjd.lowerAngle = -0.25 * Math.PI;
			rjd.upperAngle = 0.0 * Math.PI;
			rjd.enableLimit = true;
			m_world.CreateJoint(rjd);			
		}
		private function createSmall():void{
			var bodyDef:b2BodyDef = new b2BodyDef
			bodyDef.type = b2BodyType.b2_dynamicBody;
			var body:b2Body = m_world.CreateBody(bodyDef);
			
			var polyShape:b2PolygonShape = new b2PolygonShape		
			var verts:b2Vec2Array = new b2Vec2Array(3);
			verts.setAt(0,new b2Vec2( 17.63, 36.31 ));
			verts.setAt(1,new b2Vec2( 17.52, 36.69 ));
			verts.setAt(2,new b2Vec2( 17.19, 36.36 ));
			polyShape.Set(verts, 3);
			
			var polyFixtureDef:b2FixtureDef =  new b2FixtureDef;
			polyFixtureDef.shape = polyShape;
			polyFixtureDef.density = 1;
			
			body.CreateFixture(polyFixtureDef);	//assertion hits inside here			
		}
		public override function Key(code:String):void{
			switch(code){
				case 'l':
					m_joint.EnableLimit(!m_joint.IsLimitEnabled());
					break;
				case 'm':
					m_joint.EnableMotor(!m_joint.IsMotorEnabled());
					break;
			}
		}
	}
}